/**
 * WebSocket服务
 * 处理实时通信功能，如聊天、通知等
 */

import ENV_CONFIG from "../config/env";

export interface WebSocketMessage {
  type: string;
  data: any;
  timestamp: number;
}

export interface WebSocketOptions {
  onOpen?: (event: Event) => void;
  onMessage?: (message: WebSocketMessage) => void;
  onClose?: (event: CloseEvent) => void;
  onError?: (event: Event) => void;
  reconnectInterval?: number;
  maxReconnectAttempts?: number;
}

class WebSocketService {
  private ws: WebSocket | null = null;
  private url: string;
  private options: WebSocketOptions;
  private reconnectAttempts = 0;
  private maxReconnectAttempts = 5;
  private reconnectInterval = 3000;
  private isConnecting = false;
  private isManualClose = false;

  constructor(url?: string, options?: WebSocketOptions) {
    this.url = url || ENV_CONFIG.WS_BASE_URL;
    this.options = options || {};
    this.maxReconnectAttempts = options?.maxReconnectAttempts || 5;
    this.reconnectInterval = options?.reconnectInterval || 3000;
  }

  /**
   * 连接WebSocket
   */
  connect(): Promise<void> {
    return new Promise((resolve, reject) => {
      if (this.ws?.readyState === WebSocket.OPEN) {
        resolve();
        return;
      }

      if (this.isConnecting) {
        reject(new Error("WebSocket正在连接中"));
        return;
      }

      this.isConnecting = true;
      this.isManualClose = false;

      try {
        this.ws = new WebSocket(this.url);

        this.ws.onopen = (event) => {
          console.log("🔌 WebSocket连接成功");
          this.isConnecting = false;
          this.reconnectAttempts = 0;
          this.options.onOpen?.(event);
          resolve();
        };

        this.ws.onmessage = (event) => {
          try {
            const message: WebSocketMessage = JSON.parse(event.data);
            this.options.onMessage?.(message);
          } catch (error) {
            console.error("❌ WebSocket消息解析失败:", error);
          }
        };

        this.ws.onclose = (event) => {
          console.log("🔌 WebSocket连接关闭", event.code, event.reason);
          this.isConnecting = false;
          this.options.onClose?.(event);

          // 如果不是手动关闭且没有达到最大重连次数，则自动重连
          if (
            !this.isManualClose &&
            this.reconnectAttempts < this.maxReconnectAttempts
          ) {
            this.scheduleReconnect();
          }
        };

        this.ws.onerror = (event) => {
          console.error("❌ WebSocket连接错误:", event);
          this.isConnecting = false;
          this.options.onError?.(event);
          reject(new Error("WebSocket连接失败"));
        };
      } catch (error) {
        this.isConnecting = false;
        reject(error);
      }
    });
  }

  /**
   * 发送消息
   */
  send(type: string, data: any): boolean {
    if (this.ws?.readyState !== WebSocket.OPEN) {
      console.warn("⚠️ WebSocket未连接，消息发送失败");
      return false;
    }

    try {
      const message: WebSocketMessage = {
        type,
        data,
        timestamp: Date.now(),
      };
      this.ws.send(JSON.stringify(message));
      return true;
    } catch (error) {
      console.error("❌ WebSocket消息发送失败:", error);
      return false;
    }
  }

  /**
   * 关闭连接
   */
  close(): void {
    this.isManualClose = true;
    this.ws?.close();
    this.ws = null;
  }

  /**
   * 获取连接状态
   */
  getReadyState(): number {
    return this.ws?.readyState ?? WebSocket.CLOSED;
  }

  /**
   * 检查是否已连接
   */
  isConnected(): boolean {
    return this.ws?.readyState === WebSocket.OPEN;
  }

  /**
   * 安排重连
   */
  private scheduleReconnect(): void {
    this.reconnectAttempts++;
    console.log(
      `🔄 WebSocket重连中... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`
    );

    setTimeout(() => {
      this.connect().catch((error) => {
        console.error("🔄 WebSocket重连失败:", error);
      });
    }, this.reconnectInterval);
  }
}

// 创建全局WebSocket实例
let globalWebSocketService: WebSocketService | null = null;

/**
 * 获取全局WebSocket服务实例
 */
export const getWebSocketService = (
  options?: WebSocketOptions
): WebSocketService => {
  if (!globalWebSocketService) {
    globalWebSocketService = new WebSocketService(undefined, options);
  }
  return globalWebSocketService;
};

/**
 * 销毁全局WebSocket服务实例
 */
export const destroyWebSocketService = (): void => {
  if (globalWebSocketService) {
    globalWebSocketService.close();
    globalWebSocketService = null;
  }
};

/**
 * 聊天WebSocket服务
 */
export class ChatWebSocketService extends WebSocketService {
  constructor() {
    super(ENV_CONFIG.WS_BASE_URL + "/chat", {
      onMessage: (message) => {
        if (message.type === "chat") {
          // 处理聊天消息
          console.log("💬 收到聊天消息:", message.data);
        }
      },
    });
  }

  /**
   * 发送聊天消息
   */
  sendChatMessage(content: string, receiverId?: string): boolean {
    return this.send("chat", {
      content,
      receiverId,
      senderId: localStorage.getItem("userId"),
    });
  }

  /**
   * 加入聊天室
   */
  joinRoom(roomId: string): boolean {
    return this.send("join", { roomId });
  }

  /**
   * 离开聊天室
   */
  leaveRoom(roomId: string): boolean {
    return this.send("leave", { roomId });
  }
}

/**
 * 通知WebSocket服务
 */
export class NotificationWebSocketService extends WebSocketService {
  constructor() {
    super(ENV_CONFIG.WS_BASE_URL + "/notification", {
      onMessage: (message) => {
        if (message.type === "notification") {
          // 处理系统通知
          console.log("🔔 收到系统通知:", message.data);
        }
      },
    });
  }

  /**
   * 订阅通知
   */
  subscribe(userId: string): boolean {
    return this.send("subscribe", { userId });
  }

  /**
   * 取消订阅
   */
  unsubscribe(userId: string): boolean {
    return this.send("unsubscribe", { userId });
  }
}

export default WebSocketService;
